package exportExcel;

import java.io.File;
import org.w3c.dom.*;
import java.util.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 *
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 *
 * @author
 * @version 1.0
 */

public class XmlReader {

    private static Map<String, Document> documents = new HashMap<String, Document>();

    //public static int times = 0;
    //use this to load any document you like
    public static void loadDocument(String filePath)
            {
        try {
            //System.out.println("--------------LOAD DOCUMENT " + (times++));
            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.
                    newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document settings = docBuilder.parse(new File(filePath));
            settings.getDocumentElement().normalize();
            documents.put(filePath, settings);
        } catch (SAXParseException saxEx) { //should log
            saxEx.printStackTrace();
          
        } catch (SAXException saxEx) { //should log
            saxEx.printStackTrace();
            
        } catch (java.io.FileNotFoundException fnfEx) { //should log
            fnfEx.printStackTrace();
            
        } catch (Throwable thrEx) { //should log
            thrEx.printStackTrace();
            
        }

    }

    //to be deleted
    public static String getUIMessage(String messageCode) {
        return getUIMessage(messageCode, null);
    }

//    to be deleted
    public static String getUIMessage(String messageCode, String[] parameters) {
        try {
            //to be placed in Client constants
            String messageFile = MessageConstants.MESSAGE_FILE;
            String delim = MessageConstants.DELIM;
            String placeHolder = MessageConstants.PLACE_HOLDER;

            //retrieved and re-format the message
            String message = null;
            StringTokenizer st = new StringTokenizer(messageCode, delim);
            String root = st.nextToken();
            String element = st.nextToken();
            message = getString(messageFile, root, element, null);
            if (message != null && parameters != null) {
                for (int i = 0; i < parameters.length; i++) {
                    message = message.replaceAll(placeHolder + (i + 1),
                                                 parameters[i]);
                }
            }
            return message;
        } catch (Throwable t) {
            return null;
        }
    }

    //type-safe get int
    public static int getInt(String doc, String root, String element,
                             int defValue) {
        String s = xmlFind(doc, root, element);
        if (s == null) {
            return defValue;
        } else {
            try {
                return Integer.parseInt(s);
            } catch (Exception e) {
                return defValue;
            }
        }
    }

    //type-safe get float
    public static float getFloat(String doc, String root, String element,
                                 float defValue) {
        String s = xmlFind(doc, root, element);
        if (s == null) {
            return defValue;
        } else {
            try {
                return Float.parseFloat(s);
            } catch (Exception e) {
                return defValue;
            }
        }
    }

    //type-safe get boolean
    public static boolean getBoolean(String doc, String root, String element,
                                     boolean defValue) {
        String s = xmlFind(doc, root, element);
        if (s == null) {
            return defValue;
        } else {
            try {
                return Boolean.getBoolean(s);
            } catch (Exception e) {
                return defValue;
            }
        }
    }

    //type-safe get string
    public static String getString(String doc, String root, String element,
                                   String defValue) {
        String s = xmlFind(doc, root, element);
        if (s == null) {
            return defValue;
        } else {
            try {
                return s;
            } catch (Exception e) {
                return defValue;
            }
        }
    }

    //get the document
    public static Document getDocument(String docPath){
        Document doc = (Document) documents.get(docPath);
        if (doc == null) { //document is not loaded yet, load it now
            loadDocument(docPath);
        }
        return (Document) documents.get(docPath);
    }

    //load all elements into a hashtable
    public static Map<String, String> loadAllElements(String docFile) {
        Map<String, String> allMessages = new HashMap<String, String>();
        try {
            Document doc = getDocument(docFile);
            loadAllElements(allMessages, doc.getChildNodes().item(0), "");
            return allMessages;
        } catch (Throwable t) {
            //t.printStackTrace();
        }
        return allMessages;
    }

    private static void loadAllElements(Map<String, String> messages, Node relRoot,
                                        String absName) {
        if (relRoot.getNodeType() == Node.ELEMENT_NODE) { //care element only
            if (relRoot.getChildNodes().getLength() == 1 &&
                relRoot.getChildNodes().item(0).getNodeType() ==
                Node.TEXT_NODE) { //to leaf
                messages.put(absName,
                             ((Element) relRoot).getChildNodes().item(0).
                             getNodeValue().trim());
                return;
            } else { //parent root
                NodeList listRoots = relRoot.getChildNodes(); //
                for (int i = 0; i < listRoots.getLength(); i++) {
                    Node childNode = listRoots.item(i);
                    loadAllElements(messages, childNode,
                                    (absName == "" ? absName :
                                     (absName + MessageConstants.DELIM)) +
                                    childNode.getNodeName());
                }
            }
        }
    }

    public static String xmlFind(Document settings, String root,
                                 String element) {
        try {
            NodeList listRoots = settings.getElementsByTagName(root); //big tag level 2
            Node rootNode = listRoots.item(0); //get the first guy, thus, dont use same name for tag in the same level
            if (rootNode.getNodeType() == Node.ELEMENT_NODE) {
                Element rootElement = (Element) rootNode; //cast to element
                NodeList listChildren = rootElement.getElementsByTagName(
                        element); //get child elements that has specified name
                Element firstNameElement = (Element) listChildren.item(0); //again get the first guy
                NodeList textList = firstNameElement.getChildNodes();
                //System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!: " + ((Node)textFNList.item(0)).getNodeValue().trim());
                Node n = (Node) textList.item(0);
                if (n == null) {
                    return null;
                }
                return ((Node) textList.item(0)).getNodeValue().trim(); //get the first text value
            }
            //System.out.println("---------------NOTHING");
        } catch (Throwable t) { //log
            
            return null;
        }
        return null;
    }

    public static String xmlFind(String doc, String root, String element) {
        try {
            //System.out.println(doc + ":" + root + " : " + element);
            Document settings = getDocument(doc);
            return xmlFind(settings, root, element);
        } catch (Throwable t) {
           
            t.printStackTrace();
            return null;
        }
    }

    public static int countXMLElements(String doc, String root) {
        int elementCount = 0;
        try {
            Document settings = getDocumentForReport(doc);
            NodeList listRoots = settings.getElementsByTagName(root); //big tag level 2
            Node rootNode = listRoots.item(0); //get the first guy, thus, dont use same name for tag in the same level
            Element rootElement = (Element) rootNode; //cast to element
            NodeList listChildren;
            if (rootElement != null) {
                listChildren = rootElement.getElementsByTagName("*"); //get child elements that has specified name
                elementCount = listChildren.getLength();
            }
        } catch (Exception ex) {
            //ex.printStackTrace();
            elementCount = 0;
        }
        return elementCount;
    }

    public static String getValueFromPosition(String doc, String root,
                                              int position) {
        String nodeValue = "";
        try {
            System.out.println("Start reading XML with root " + root);
            Document settings = getDocumentForReport(doc);
            NodeList listRoots = settings.getElementsByTagName(root); //big tag level 2
            Node rootNode = listRoots.item(0); //get the first guy, thus, dont use same name for tag in the same level
            NodeList listChildren = rootNode.getChildNodes();
            Node node = listChildren.item(position);
            String nodeName = node.getNodeName();
            //sua lai cho nay
            nodeValue = getString(doc, root, nodeName, "").toLowerCase();
            System.out.println("Node Name:" + nodeName + " has Node Value:" +
                               nodeValue);
        } catch (Exception ex) {
            //ex.printStackTrace();
            nodeValue = "";
        }
        return nodeValue;
    }

    //get the document
    public static Document getDocumentForReport(String docPath)
            {
        Document doc = (Document) documents.get(docPath);
        //if (doc == null) { //document is not loaded yet, load it now
        loadDocument(docPath);
        //}
        return (Document) documents.get(docPath);
    }

    public static Map<String, String> getAttributes(String doc, String root, int position)
   {
    	 Map<String, String> hashAttribute = new HashMap<String, String>();
      try {
          Document settings = getDocumentForReport(doc);
          NodeList listRoots = settings.getElementsByTagName(root); //big tag level 2
          Node rootNode = listRoots.item(0); //get the first guy, thus, dont use same name for tag in the same level
          NodeList listChildren = rootNode.getChildNodes();
          Node node = listChildren.item(position);
          NamedNodeMap attributes = node.getAttributes();
          for(int i=0; i<attributes.getLength(); i++)
          {
              hashAttribute.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());
          }
      } catch (Exception ex) {
          ex.printStackTrace();
      }
      return hashAttribute;
   }

}
